package ru.shutoff.cgstarter; import android.app.ActivityManager; import android.app.UiModeManager; import android.app.admin.DevicePolicyManager; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Build; import android.os.Bundle; import android.os.CountDownTimer; import android.preference.PreferenceManager; import android.telephony.SmsMessage; import android.widget.Toast; import com.jaredrummler.android.processes.ProcessManager; import com.jaredrummler.android.processes.models.AndroidAppProcess; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CarMonitor extends BroadcastReceiver { static private final String START = "ru.shutoff.cgstarter.START"; static private final String FIRE = "com.twofortyfouram.locale.intent.action.FIRE_SETTING"; SensorManager sensorManager; Sensor sensorAccelerometer; Sensor sensorMagnetic; SensorEventListener sensorEventListener; float[] gravity; float[] magnetic; float[] orientation; private CountDownTimer power_timer; private CountDownTimer power_kill_timer; private CountDownTimer dock_kill_timer; private CountDownTimer bt_kill_timer; static void startCG(Context context, String route, String route_points, SearchActivity.Address addr) { if (route.equals("-")) { MainActivity.removeRoute(context); } else if (!route.equals("")) { MainActivity.createRoute(context, route, route_points, addr); } if (!MainActivity.setState(context, new State.OnBadGPS() { @Override public void gps_message(Context context) { Toast toast = Toast.makeText(context, context.getString(R.string.no_gps_title), Toast.LENGTH_SHORT); toast.show(); } })) { MainActivity.setState(context, null); } Intent run = context.getPackageManager().getLaunchIntentForPackage(State.CG_Package(context)); if (run == null) { Toast toast = Toast.makeText(context, context.getString(R.string.no_cg), Toast.LENGTH_SHORT); toast.show(); return; } context.startActivity(run); Intent service = new Intent(context, OnExitService.class); service.setAction(OnExitService.START); context.startService(service); } static void killCG(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses(); if (procInfos == null) return; int i; for (i = 0; i < procInfos.size(); i++) { ActivityManager.RunningAppProcessInfo proc = procInfos.get(i); if (proc.processName.equals(State.CG_Package(context))) { State.doRoot(context, "kill " + proc.pid, true); } } return; } List<AndroidAppProcess> processes = ProcessManager.getRunningAppProcesses(); String pkg_name = State.CG_Package(context); for (AndroidAppProcess process : processes) { if (pkg_name.equals(process.name)) { State.doRoot(context, "kill " + process.pid, true); return; } } } static void lockDevice(Context context) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.lockNow(); } } catch (Exception ex) { // ignore } } @Override public void onReceive(final Context context, Intent intent) { if (intent == null) return; String action = intent.getAction(); if (action == null) return; if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) && action.equals(UiModeManager.ACTION_ENTER_CAR_MODE)) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); if (preferences.getBoolean(State.CAR_MODE, false)) { setCarMode(context, true); abortBroadcast(); } } if (action.equals(Intent.ACTION_DOCK_EVENT)) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); if (preferences.getBoolean(State.CAR_MODE, false)) { int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, -1); setCarMode(context, (dockState == Intent.EXTRA_DOCK_STATE_CAR)); abortBroadcast(); } } if (action.equals("android.provider.Telephony.SMS_RECEIVED")) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); if (!preferences.getBoolean(State.SHOW_SMS, false)) return; Object[] pduArray = (Object[]) intent.getExtras().get("pdus"); SmsMessage[] messages = new SmsMessage[pduArray.length]; for (int i = 0; i < pduArray.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]); } final String sms_from = messages[0].getOriginatingAddress(); StringBuilder bodyText = new StringBuilder(); for (SmsMessage m : messages) { bodyText.append(m.getMessageBody()); } try { final String body = bodyText.toString(); Pattern pattern = Pattern.compile("([0-9]{1,2}\\.[0-9]{4,7})[^0-9]+([0-9]{1,2}\\.[0-9]{4,7})"); Matcher matcher = pattern.matcher(body); if (!matcher.find()) return; Intent i = new Intent(context, SmsDialog.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.putExtra(State.LATITUDE, matcher.group(1)); i.putExtra(State.LONGITUDE, matcher.group(2)); i.putExtra(State.INFO, sms_from); i.putExtra(State.TEXT, body); context.startActivity(i); } catch (Exception ex) { // ignore } } if (action.equals(Intent.ACTION_POWER_CONNECTED)) { if (power_kill_timer != null) { power_kill_timer.cancel(); power_kill_timer = null; } if (!OnExitService.is_run && (power_timer == null)) { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); String interval = preferences.getString(State.POWER_TIME, ""); if (State.inInterval(interval)) { orientation = null; if (preferences.getBoolean(State.VERTICAL, true)) { if (sensorEventListener == null) { sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); if (sensorAccelerometer == null) sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); if (sensorMagnetic == null) sensorMagnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); if (sensorEventListener == null) { sensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) magnetic = event.values; if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) gravity = event.values; if ((gravity == null) || (magnetic == null)) return; float[] R = new float[9]; float[] I = new float[9]; if (!SensorManager.getRotationMatrix(R, I, gravity, magnetic)) return; if (orientation == null) orientation = new float[3]; SensorManager.getOrientation(R, orientation); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; sensorManager.registerListener(sensorEventListener, sensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(sensorEventListener, sensorMagnetic, SensorManager.SENSOR_DELAY_NORMAL); } } } power_timer = new CountDownTimer(10000, 2000) { @Override public void onTick(long millisUntilFinished) { if (preferences.getBoolean(State.VERTICAL, true)) { if (orientation == null) return; if ((Math.abs(orientation[1]) + Math.abs(orientation[2])) < 1) { if (sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener); sensorEventListener = null; } orientation = null; if (power_timer != null) power_timer.cancel(); power_timer = null; return; } orientation = null; } if (sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener); sensorEventListener = null; } if (power_timer != null) power_timer.cancel(); power_timer = null; context.sendBroadcast(new Intent("com.smartmadsoft.xposed.nolockhome.UNLOCK")); if (!OnExitService.isRunCG(context)) { Intent run = new Intent(context, MainActivity.class); run.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(run); } } @Override public void onFinish() { if (sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener); sensorEventListener = null; } orientation = null; } }; power_timer.start(); } } } if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) { if (power_timer != null) { power_timer.cancel(); power_timer = null; } if (power_kill_timer != null) { power_kill_timer.cancel(); power_kill_timer = null; } if (OnExitService.is_run) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); if (preferences.getBoolean(State.KILL_POWER, false)) { power_kill_timer = new CountDownTimer(3000, 3000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { State.appendLog("Exit on power"); power_kill_timer = null; OnExitService.force_exit = true; killCG(context); lockDevice(context); } }; power_kill_timer.start(); } } } if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); String devices = preferences.getString(State.BT_DEVICES, ""); if (!devices.equals("")) devices += ";"; devices += device.getAddress(); State.appendLog("ACL: " + devices); SharedPreferences.Editor ed = preferences.edit(); ed.putString(State.BT_DEVICES, devices); ed.commit(); if (bt_kill_timer != null) { bt_kill_timer.cancel(); bt_kill_timer = null; } } if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); State.appendLog("-ACL: " + device.getAddress()); OnExitService.turnOffBT(context, device.getAddress()); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); if (preferences.getBoolean(State.KILL_BT, false) && preferences.getString(State.BT_DEVICES, "").equals("-")) { State.appendLog("Exit on BT"); if (bt_kill_timer == null) { bt_kill_timer = new CountDownTimer(3000, 3000) { @Override public void onTick(long l) { } @Override public void onFinish() { State.appendLog("Exit on BT timer"); bt_kill_timer = null; OnExitService.force_exit = true; killCG(context); lockDevice(context); } }; bt_kill_timer.start(); } } } if (action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) { OnExitService.call_number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); Pattern pattern = Pattern.compile("([0-9]{1,2}\\.[0-9]{4,7})[^0-9]+([0-9]{1,2}\\.[0-9]{4,7})"); Matcher matcher = pattern.matcher(OnExitService.call_number); if (!matcher.find()) return; Intent i = new Intent(context, SmsDialog.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.putExtra(State.LATITUDE, matcher.group(1)); i.putExtra(State.LONGITUDE, matcher.group(2)); i.putExtra(State.INFO, R.string.go); i.putExtra(State.TEXT, OnExitService.call_number); context.startActivity(i); abortBroadcast(); } if (action.equals(FIRE)) { Bundle data = intent.getBundleExtra(EditActivity.EXTRA_BUNDLE); try { String route = data.get(State.ROUTE).toString(); String points = data.get(State.POINTS).toString(); startCG(context, route, points, null); } catch (Exception ex) { // ignore } } if (action.equals(START)) { String route = intent.getStringExtra("ROUTE"); String route_points = intent.getStringExtra("POINTS"); if (route == null) route = ""; if (route_points == null) route_points = ""; int n_route = intent.getIntExtra("ROUTE", 0); if (n_route > 0) { State.Point[] points = State.get(context, false); if (n_route > points.length) return; State.Point p = points[n_route - 1]; if ((p.lat.equals("")) && (p.lng.equals(""))) return; route = p.lat + "|" + p.lng; route_points = p.points; } else if (n_route < 0) { MainActivity.removeRoute(context); route = ""; } startCG(context, route, route_points, null); } } void setCarMode(final Context context, boolean newMode) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); boolean curMode = preferences.getBoolean(State.CAR_STATE, false); if (curMode != newMode) { SharedPreferences.Editor ed = preferences.edit(); ed.putBoolean(State.CAR_STATE, newMode); ed.commit(); if (newMode) { if (!OnExitService.isRunCG(context)) { Intent run = new Intent(context, MainActivity.class); run.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(run); ed.commit(); } if (dock_kill_timer != null) { dock_kill_timer.cancel(); dock_kill_timer = null; } } else { if (preferences.getBoolean(State.KILL_CAR, false)) { dock_kill_timer = new CountDownTimer(2000, 2000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { State.appendLog("Exit on car mode"); dock_kill_timer = null; OnExitService.force_exit = true; killCG(context); lockDevice(context); } }; dock_kill_timer.start(); } } } } }